package com.zidongxiangxi.sharding.job.core.node;

import com.zidongxiangxi.sharding.job.core.ShardingJobRegistry;
import com.zidongxiangxi.sharding.job.core.storage.NodeStorage;

import java.util.List;
import java.util.Objects;

/**
 * 实例节点
 *
 * @author chenxudong
 * @date 2021/02/07
 */
public class InstancesNode extends AbstractNode {
    private static final String ROOT = "instances";
    private static final String INSTANCES = ROOT + "/%s";
    private static final String LOCAL_INSTANCE = ROOT + "/" + ShardingJobRegistry.getInstance().getLocalInstanceId();

    private final String instancesNodeFullPath;
    private final String localInstanceFullPath;

    public InstancesNode(final String jobName, final NodeStorage storage) {
        super(jobName, storage);
        instancesNodeFullPath = getFullPath(ROOT);
        localInstanceFullPath = getFullPath(LOCAL_INSTANCE);
    }

    public List<String> getAllInstanceIds() {
        return storage.getJobNodeChildrenKeys(ROOT);
    }

    public void persistLocalInstanceOnline() {
        storage.fillEphemeralJobNode(LOCAL_INSTANCE, "");
    }

    public boolean isLocalJobInstanceExisted() {
        return storage.isJobNodeExisted(LOCAL_INSTANCE);
    }

    /**
     * 判断是否实例节点
     *
     * @param path 节点路径
     * @return 是否实例节点
     */
    public boolean isInstancesPath(final String path) {
        return path.startsWith(instancesNodeFullPath);
    }

    /**
     * 判断是否实例id节点
     *
     * @param path 节点路径
     * @return 是否实例id节点
     */
    public boolean isInstanceIdPath(final String path) {
        return isInstancesPath(path) && !path.endsWith("/" + ROOT);
    }

    /**
     * 获取本地实例的相对路径
     *
     * @return 相对路径
     */
    public String getLocalInstanceFullPath() {
        return localInstanceFullPath;
    }

    /**
     * 是否本地实例
     *
     * @param path 节点路径
     * @return 是否本地实例
     */
    public boolean isLocalInstancePath(final String path) {
        return Objects.equals(localInstanceFullPath, path);
    }

    /**
     * 删除本地实例节点
     */
    public void removeLocalInstance() {
        storage.removeJobNodeIfExisted(LOCAL_INSTANCE);
    }

}
